package com.i2works.smartluolong.web.controller.oauth;

import com.alibaba.fastjson.JSONObject;
import com.i2works.smartluolong.utils.base.AppConstant;
import com.i2works.smartluolong.utils.base.MsgEnum;
import com.i2works.smartluolong.utils.common.BaseUtils;
import com.i2works.smartluolong.utils.common.DateUtils;
import com.i2works.smartluolong.utils.entity.R;
import com.i2works.smartluolong.utils.entity.Result;
import com.i2works.smartluolong.utils.exception.ServiceException;
import com.i2works.smartluolong.utils.shiro.SmartLuoLongToken;
import com.i2works.smartluolong.utils.web.HtmlConstant;
import com.i2works.smartluolong.web.entity.user.UserAccountDO;
import com.i2works.smartluolong.web.entity.user.UserAccountExtendDO;
import com.i2works.smartluolong.web.entity.user.UserAccountQuery;
import com.i2works.smartluolong.web.entity.user.UserLoginVO;
import com.i2works.smartluolong.web.service.user.IUserAccountExtendService;
import com.i2works.smartluolong.web.service.user.IUserAccountService;
import com.i2works.smartluolong.web.utils.BaseModule;
import com.i2works.smartluolong.web.utils.HttpUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;


/**
  * 个人接口
 * Created by liu yapeng on 2018/10/15.
 */

 @Controller
 @RequestMapping(value = "user/")
public class userOauthController extends BaseModule {
	 
	 /**
	     * 通用错误键名
	     */
	   public final static String MESSAGE_CODE = "messageCode";
	 
	   private final IUserAccountService userAccountService;
	   
	   private final IUserAccountExtendService userAccountExtendService;

	    @Autowired
	    public userOauthController(IUserAccountService userAccountService,IUserAccountExtendService userAccountExtendService) {
	        this.userAccountService = userAccountService;
	        this.userAccountExtendService=userAccountExtendService;
	    }

    private final String personalUaaUrl = "https://puser.hnzwfw.gov.cn:8081";
    private final String personalWebUrl = "https://puser.hnzwfw.gov.cn:8082";
    private final String legalUaaUrl ="https://puser.hnzwfw.gov.cn:8083";//法人同个人，作为区分，实则和个人地址等效
    private final  String appId ="0000xjy1";
	private final  String appSecret ="23a50ce2-bb07-400c-a469-6d6f9f4c84d";
	
	private String serviceCode=""; //事项编码


	/**
        * 政务平台跳转
     * @param sid 事项编码
     * @param logintype 用户类型
     */
    @GetMapping(value = "zwptLogin")
    public String zwptLogin(String sid,String logintype) {
    	serviceCode=sid;
    	String thisUrl =AppConstant.WEB_URL;
    	String url= HtmlConstant.REDIRECT+personalUaaUrl+"/login?client_id="+appId+"&redirect_uri="+thisUrl+"/user/zwptToken&response_type=code&scope=openid&state=STATE";
    	return url;
    }
    
    /**
    *
     * 通过code换取token
    * @param code
    * @return
    * @throws IOException
    */
   @RequestMapping(value = "zwptToken")
   public String zwptToken(String code) throws IOException {
   	String thisUrl =AppConstant.WEB_URL;
   	String queryString =  "client_id="+appId+"&client_secret="+appSecret+"0&code=" + code
   			+ "&redirect_uri="+thisUrl+"/user/oauth2/token&grant_type=authorization_code";
   	String url = personalUaaUrl+"/oauth2/token";
   	String data = HttpUtils.connections(url,"POST",queryString, "application/x-www-form-urlencoded");
   	JSONObject json=JSONObject.parseObject(data);
   	String token=json.getString("access_token");
   	try {
   		//本地登陆系统登陆
   		localLogin(token);
   	} catch (ServiceException e) {
   		e.printStackTrace();
   	}
   	return HtmlConstant.REDIRECT+"/unifyDeclare/info/"+serviceCode;
   }
   

    /**
     * web个人登陆
     * @return
     */
    @GetMapping(value = "personLogin")
    public String personLogin() {
    	String thisUrl =AppConstant.WEB_URL;
    	String url= HtmlConstant.REDIRECT+personalUaaUrl+"/login?client_id="+appId+"&redirect_uri="+thisUrl+"/user/personToken&response_type=code&scope=openid&state=STATE";
    	return url;
    }
    
    

    /**
     * web法人登陆
     * @return
     */
    @GetMapping(value = "legalLogin")
    public String legalLogin() {
    	String thisUrl =AppConstant.WEB_URL;
    	return HtmlConstant.REDIRECT+legalUaaUrl+"/login?client_id="+appId+"&redirect_uri="+thisUrl+"/user/legalToken&response_type=code&scope=openid&state=STATE";
    }
    /**
     *
     * 通过code换取个人token
     * @param code
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "personToken")
    public String personToken(String code) throws IOException {
    	String thisUrl =AppConstant.WEB_URL;
    	String queryString =  "client_id="+appId+"&client_secret="+appSecret+"0&code=" + code
    			+ "&redirect_uri="+thisUrl+"/user/oauth2/token&grant_type=authorization_code";
    	String url = personalUaaUrl+"/oauth2/token";
    	String data = HttpUtils.connections(url,"POST",queryString, "application/x-www-form-urlencoded");
    	JSONObject json=JSONObject.parseObject(data);
    	String token=json.getString("access_token");
    	try {
    		//本地登陆系统登陆
    		localLogin(token);
    	} catch (ServiceException e) {
    		e.printStackTrace();
    	}
    	return HtmlConstant.REDIRECT+"/";
    }
    
    
    /**
    *
    * 通过code换取法人token
    * @param code
    * @return
    * @throws IOException
    */
   @RequestMapping(value = "legalToken")
   public String legalToken(String code) throws IOException {
   	String thisUrl =AppConstant.WEB_URL;
   	String queryString =  "client_id="+appId+"&client_secret="+appSecret+"0&code=" + code
   			+ "&redirect_uri="+thisUrl+"/user/oauth2/token&grant_type=authorization_code";
   	String url = legalUaaUrl+"/oauth2/token";
   	String data = HttpUtils.connections(url,"POST",queryString, "application/x-www-form-urlencoded");
   	JSONObject json=JSONObject.parseObject(data);
   	String token=json.getString("access_token");
   	try {
   		//本地登陆系统登陆
   		localLogin(token);
   	} catch (ServiceException e) {
   		e.printStackTrace();
   	}
   	return HtmlConstant.REDIRECT+"/";
   }
   
   
    /**
       * 本地登陆
     * @throws ServiceException 
     * */
    public void localLogin(String token) throws ServiceException {
    	    String userData=getBriefUser(token);
    		UserAccountDO userLogin=JSONtoUserDO(userData);
    		UserAccountQuery  query=new UserAccountQuery();
    		query.setUserName(userLogin.getUserName());
    		Integer count = userAccountService.queryCheck(query);
    		String userExtendData =getDetailedNormalUser(token);
    	    UserAccountExtendDO userExtend=	 JSONtoUserExtendDO(userExtendData);
    		if(count==0) {
    			userAccountService.saveRegisterUser(userLogin);
    			userExtend.setUserId(userLogin.getId());
    			userAccountExtendService.save(userExtend);
    		}else {
    			userAccountService.updateByPhone(userLogin);
    			userLogin=userAccountService.queryLoginUser(userLogin.getUserName());
    			userExtend.setUserId(userLogin.getId());
    			userAccountExtendService.updateByUserId(userExtend);
    		}
    		Subject subject = SecurityUtils.getSubject();
    		subject.getSession().setAttribute("token", token);
    		SmartLuoLongToken smartLuoLongToken = new SmartLuoLongToken(userLogin.getUserName());
    		//登录
    		subject.login(smartLuoLongToken);

    	
    }
    
    private UserAccountDO  JSONtoUserDO(String userData) {
    	ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
    	JSONObject userJson=JSONObject.parseObject(userData);
		UserAccountDO userLogin =new UserAccountDO();
		userLogin.setUserName(userJson.getString("userName"));
		userLogin.setPhone(userJson.getString("mobile"));
		userLogin.setEmail(userJson.getString("email"));
		userLogin.setOpenId(userJson.getString("userId"));
		userLogin.setCategory(Integer.valueOf(userJson.getString("category")));
		userLogin.setLoginIp(BaseUtils.getIP(request));
		userLogin.setPassword("123456");
		userLogin.setStatus(1);
		userLogin.setCreateName(userJson.getString("userName"));
		userLogin.setUpdateName(userJson.getString("userName"));
    	return userLogin;
    }
    
    private UserAccountExtendDO JSONtoUserExtendDO(String userExtend) {
    	JSONObject userExtendJson=JSONObject.parseObject(userExtend);
    	UserAccountExtendDO  userExtendDO=new UserAccountExtendDO();
    	String address=userExtendJson.getString("addresses");
    	userExtendDO.setAddress(address.replace("[","").replace("]",""));
    	String idcard=userExtendJson.getString("idCode");
    	if(idcard!=null) {
    	userExtendDO.setIdcard(idcard);
    	Date birthday=DateUtils.getBirthdayByIDcard(userExtendJson.getString("idCode"));
    	userExtendDO.setBirthday(birthday);
    	Integer age=DateUtils.getAgeByIDcard(userExtendJson.getString("idCode"));
    	userExtendDO.setAge(age);
    	}
    	userExtendDO.setAvatar(userExtendJson.getString("imgAddr"));
    	userExtendDO.setRealName(userExtendJson.getString("realName"));
    	userExtendDO.setSex(userExtendJson.getInteger("gender"));
    	userExtendDO.setCreateName(userExtendJson.getString("account"));
    	userExtendDO.setUpdateName(userExtendJson.getString("account"));
    	
    	return userExtendDO;
    }
    /**
    * 用户登录页面
    */
   @GetMapping("/login")
   public String login(@RequestParam(value = MESSAGE_CODE, required = false) String messageCode, Model model, HttpServletRequest request) {
       if (StringUtils.isNotBlank(messageCode)) {
           model.addAttribute(MESSAGE_CODE, messageCode);
       }
       return "/user/login";
   }

    /**
     *
          * 一体机登陆
     * @param username
     * @param password
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/login")
    @ResponseBody
    public Result token(@RequestParam("username") String username,@RequestParam("password") String password) throws IOException {
    	try {
    	 String url = personalUaaUrl+"/uaa/obtainToken";
         JSONObject param = new JSONObject();
        param.put("username",username);
        param.put("password",password);
        param.put("client_id",appId);
        String data = HttpUtils.connections(url, "POST",param.toString(),"application/json");
        JSONObject json=JSONObject.parseObject(data);
    	String token=json.getString("accessToken");
        //本地登陆系统登陆
        localLogin(token);
        //用于登录后跳转到之前网址
       /* ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
        String backUrl = WebUtils.getSavedRequest(request).getRequestUrl();
        backUrl=backUrl==null?"/user/index":backUrl;*/
	   return R.success(MsgEnum.ACCESS_LOGIN_SUCCESS.getMsg(), "/");
       } catch (ServiceException e) {
    	   return R.error(MsgEnum.LOGIN_FAILED.getMsg());
       }
    
    }
    
    
    /**
     * 根据token查询用户基本信息
     * @param token token是使用code换取的token的全部信息
     * @return
     */
    @RequestMapping(value = "getBriefUser")
    public String getBriefUser(String token) {
        String url = personalWebUrl+"/openApi/user/getBriefUser";
        String queryString = "token="+token;//queryString是要传的参数
        String result = HttpUtils.sendGet(url,queryString);
        return result;
    }
    
    /**
     * 根据token查询个人用户详细信息
     * @param token
     * @return
     */
    @RequestMapping(value = "getDetailedNormalUser")
    public String getDetailedNormalUser(String token) {
        String url = personalWebUrl+"/openApi/user/getDetailedNormalUser";
        String queryString = "token="+token;// queryString是要传的参数
        String result = HttpUtils.sendGet(url,queryString);
        return result;
    }

    /**
     * 根据id查询用户基本信息
     * @param openId
     * @return
     */
    @RequestMapping(value = "getBriefUserById")
    public String getBriefUserById(String openId) {
        String url = personalWebUrl+"/openApi/user/getBriefUserById";
        String queryString = "id="+openId;// queryString是要传的参数
        String result = HttpUtils.sendGet(url,queryString);
        return result;
    }
    
    /**
     * 根据id查询个人用户详细信息，还需带上appId（是否是应用管理员需要用到）
     * @param openId
     * @return
     */
    @RequestMapping(value = "getDetailedNormalUserById")
    public String getDetailedNormalUserById(String openId) {
        String url = personalWebUrl+"/openApi/user/getDetailedNormalUserById";
        String queryString = "id="+openId;// queryString是要传的参数
        String result = HttpUtils.sendGet(url,queryString);
        return result;
    }

    
    /**
     * 该接口是用于手机注册时发送手机验证码
     * @param mobile 
     * @return
     */
    @PostMapping(value = "getSms")
    @ResponseBody
    public Result getSms(String mobile) {
        String url = personalUaaUrl+"/api/user/sms";
        String queryString = "mobile="+mobile;//queryString是要传的参数
        String result = HttpUtils.doGet(url+"?"+queryString);
        return R.success();
    }


    /**
     * 账号元素占用检测
     *
     * @param phone   账号/邮箱/手机号
     * @return Boolean 存在返回false,不存在返回true
     */
    @PostMapping(value = {"/check"})
    @ResponseBody
    public Boolean check(@RequestParam(required = false, value = "param") String phone) {
        String result=	isAccountExit(phone);
        result=result.replace("\r\n","");
        if(result!=null) {
     	   return	   !Boolean.parseBoolean(result);
        }
         return false;
    }

	public String isAccountExit(String userName) {
		String url = personalUaaUrl+"/api/user/isAccountExit";
		String  queryString = "userName="+userName;
		String result = HttpUtils.doGet(url+"?"+queryString);
		return result;
	}
	
	
	public Result registerVerifyMobile(String mobile,String captcha) {
		String url = personalUaaUrl+"/api/user/registerVerifyMobile";
		String  queryString = "mobile="+mobile+"&captcha="+captcha;
		String result = HttpUtils.doGet(url+"?"+queryString);
		result=result.replace("\r\n","");
		if(result!=null) {
			if(Boolean.parseBoolean(result)) {
				return R.success();
			}
		}
		return R.error();
	}
	
	/** 
	 * 手机注册
	 * @param  Stirng mobile,,
	 * @param Stirng captcha
	 * @param Stirng passwd
	 * @param  Stirng passwdConfirm
	 * 
	 * */
	
	public String mobileRegister(JSONObject param) {
		String url = personalUaaUrl+"/api/user/mobileRegister";
		String result = HttpUtils.executePost(url, param.toString());
		return result;
	}


   /**
     * 用户注册页面
     */
    @GetMapping(value = {"/register"})
    public String register(
            @RequestParam(value = MESSAGE_CODE, required = false) String messageCode,
            @RequestParam(value = "operatorId",required = false) Integer operatorId,
            Model model, HttpServletRequest request) {
        if (StringUtils.isNotBlank(messageCode)) {
            model.addAttribute(MESSAGE_CODE, messageCode);
        }
        return "/user/register";
    }

    
    /**
    * 找回密码页面
    */
   @GetMapping("/resetPassword")
   public String resetPassword() {
       return "/user/resetPassword";
   }

    
	/**
	 * 用户注册方法
	 */
	@PostMapping("/register")
	@ResponseBody
	public Result register(@ModelAttribute UserLoginVO userLoginVO, HttpServletRequest request, RedirectAttributes redirect) {

		//实体
		if (null == userLoginVO) {
			return R.error(MsgEnum.ATTRS_EMPTY.getMsg());
		}

		//手机号
		if (StringUtils.isBlank(userLoginVO.getPhone())) {
			return R.error(MsgEnum.ACCESS_PHONE_NULL.getMsg());
		}

		//账号密码
		if (StringUtils.isAnyBlank(userLoginVO.getPassword(),userLoginVO.getConfirmPassword())) {
			return R.error(MsgEnum.ACCESS_PASSWORD_EMPTY.getMsg());
		}

		//两次密码对比
		if (!StringUtils.equalsIgnoreCase(userLoginVO.getPassword(), userLoginVO.getConfirmPassword())) {
			return R.error(MsgEnum.ACCESS_CONFIRMPASSWORD_ERROR.getMsg());
		}

		//短信验证码
		Result result = registerVerifyMobile(userLoginVO.getPhone(), userLoginVO.getCode());
		if (!result.getSuccess()) {
			return result;
		}

		JSONObject param=new JSONObject();
		param.put("mobile", userLoginVO.getPhone());
		param.put("captcha", userLoginVO.getCode());
		param.put("passwd", userLoginVO.getPassword());
		param.put("passwdConfirm", userLoginVO.getConfirmPassword());
		String accountId= mobileRegister(param);
		if(accountId!=null) {
			//用于登录后跳转到之前网址
			return R.success(MsgEnum.ACCESS_REG_SUCCESS.getMsg(), "/user/login");   
		}else {
			//  注册异常
			return R.error(MsgEnum.REGIST_FAILED.getMsg());
		}


	}

    
    
    
    /**
     * 该接口是用于手机注册时发送手机验证码
     * @param mobile 
     * @return
     */
    @PostMapping(value = "sendForgetMobile")
    @ResponseBody
    public Result sendForgetMobile(String mobile) {
        String url = personalUaaUrl+"/api/user/sendForgetMobile";
        JSONObject param=new JSONObject();
        param.put("mobile", mobile);
        String result = HttpUtils.executePost(url, param.toString());
        if(Boolean.valueOf(result)) {
        	return R.success();
        }else {
        	return R.error();
        }
    }
    /**
     * 忘记密码提交
     * @param mobile
     * @param code
     * @param passwd
     * @param passwdConfirm
     * 
     * */

    @PostMapping("/resetPassword")
    @ResponseBody
    public Result mobileRestPasswordOne(String phone,String code,String password,String confirmPassword) {
        String url = personalUaaUrl+"/api/user/mobileRestPasswordOne";
        JSONObject param=new JSONObject();
        param.put("mobile", phone);
        param.put("captcha", code);
        param.put("passwd", password);
        param.put("passwdConfirm", confirmPassword);
        String result = HttpUtils.connections(url, "POST",param.toString(),"application/json");
        if(Boolean.valueOf(result)) {
        	 return R.success();
        }
        return R.error();
    }
    

    
    /**
     * 用户注销后需要调用统一认证中心的注销接口（后台调用，无需重定向）
     * @throws IOException
     */
    @RequestMapping(value = "userLogout")
    public String userLogout(String token) {
        String url = personalUaaUrl+"/userLogout";
        JSONObject json = new JSONObject();
        json.put("token",token);
        String queryString = json.toString();
        String dataFormat = "application/json";
        String result = HttpUtils.connections(url, "POST", queryString, dataFormat);
        return result;
    }
    
    /**
     * 用户注销后需要调用统一认证中心的注销接口（后台调用，无需重定向）
     * @throws IOException
     */
    @GetMapping(value = "logout")
    public String logout(HttpServletRequest request) {
    	Subject subject = SecurityUtils.getSubject();
    	String token=(String) subject.getSession().getAttribute("token");
    	if(token!=null) {
    		userLogout(token);
    	}
          if (subject.isAuthenticated()) {
              // session 会销毁，在SessionListener监听session销毁，清理权限缓存
              subject.logout();
              //获取上一页存值
              SavedRequest saveRequest = WebUtils.getSavedRequest(request);
              if (saveRequest != null && StringUtils.isNotBlank(saveRequest.getRequestUrl())) {
                  return HtmlConstant.REDIRECT + saveRequest.getRequestUrl();
              }
          }
          return HtmlConstant.REDIRECT + "/";
    }
    



}
